package controllers

import (
	"fmt"
	"git.oschina.net/dddailing/deepserver/models"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/astaxie/beego/utils"
	"github.com/dailing/levlog"
	"io/ioutil"
	"os"
	"os/exec"
	"text/template"
	"strings"
)

type ReportController struct {
	beego.Controller
}

func (c *ReportController) Get() {
	pid := c.Ctx.Input.Param(":Patient")
	if pid == "" {
		c.Abort("404")
	}
	o := orm.NewOrm()
	dr := models.DiagnoseRecord{}
	pa := models.PatientRecord{}
	ddr := make([]models.DiagoniseDetail, 0)
	ddl := make([]models.DiagoniseDetail, 0)
	beego.Trace("get report for ", pid)
	o.QueryTable(&models.DiagnoseRecord{}).
		Filter("patient_id", pid).
		One(&dr)
	pa.ID = dr.PatientID
	err := o.Read(&pa)
	levlog.E(err)
	if err != nil {
		c.Data["err"] = err
		c.TplName = "ErrorPage.html"
		return
	}
	c.TplName = "NotFinished.html"

	_, err = o.QueryTable(&models.DiagoniseDetail{}).
		Filter("patient_id", pa.ID).
		Filter("WhichEye", "left").
		All(&ddl)
	c.Data["err"] = err
	if err != nil {
		c.TplName = "ErrorPage.html"
		return
	}
	if len(ddl) < 4 {
		beego.Trace("Return, not enough report")
		return
	}

	_, err = o.QueryTable(&models.DiagoniseDetail{}).
		Filter("patient_id", pa.ID).
		Filter("WhichEye", "right").
		All(&ddr)
	c.Data["err"] = err
	if err != nil {
		c.TplName = "ErrorPage.html"
		return
	}
	if len(ddr) < 4 {
		beego.Trace("Return, not enough report ", len(ddr))
		return
	}
	// begin start report
	reportName := fmt.Sprint("data/report_", pid, ".pdf")
	if utils.FileExists(reportName) {
		content, err := ioutil.ReadFile(reportName)
		levlog.E(err)
		c.Ctx.Output.Body(content)
		return
	}
	beego.Trace("Generate report")
	type tpl struct {
		Name, Gender, Eyesight, Number string
		Age                            int
		Time                           string
		Imgr, Imgl                     string
		Datatablel, Datatabler         string
		Desp, Diag, Sugg               string
		File                           string
	}
	tplcontent := tpl{
		Name:     pa.PatientName,
		Gender:   pa.PatientGender,
		Age:      pa.PatientAge,
		Eyesight: pa.PatientEyesight,
		Number:   pa.PatientID,
		Time:     pa.Created.Format("2006-01-02 15:04:05"),
		Imgr:     "data/" + GetOriginalImageName(pa.ID, "right"),
		Imgl:     "data/" + GetOriginalImageName(pa.ID, "left"),
	}
	GenDesp := func(eye string, dd []models.DiagoniseDetail) string {
		str := eye
		for _, d := range dd {
			if d.Type == "ve" {
				continue
			}
			str += d.Desp + ","
		}
		str = str[:len(str) - 1]
		return str + "。"
	}
	genTale := func(dd []models.DiagoniseDetail) string {
		m := make(map[string]int)
		m["ve"] = 1
		m["ma"] = 2
		m["ha"] = 3
		m["ex"] = 4
		a := make(map[int](map[int]string))
		for i := 0; i < 4; i++ {
			a[i] = make(map[int]string)
		}
		for _, d := range dd {
			a[0][m[d.Type]] = fmt.Sprint(d.Count)
			a[1][m[d.Type]] = fmt.Sprint(d.Area)
			a[2][m[d.Type]] = fmt.Sprintf("%2.2f\\%%", d.Percentage * 100)
		}
		a[0][0] = "病变数量"
		a[1][0] = "病变面积"
		a[2][0] = "病变百分比"
		a[0][5] = "0"
		a[1][5] = "0"
		a[2][5] = "0"
		str := ""
		for ind1 := 0; ind1 < len(a); ind1 += 1 {
			mm := a[ind1]
			if len(mm) < 5 {
				continue
			}
			for ind2 := 0; ind2 < len(mm); ind2++ {
				field := mm[ind2]
				str += fmt.Sprint(field, "&")
			}
			str = str[:len(str) - 1]
			str += ` \\ \hline ` + "\n"
		}
		return str
	}
	GenDegree := func(eye string, dd []models.DiagoniseDetail) string {
		m := make(map[string]models.DiagoniseDetail)
		for _, d := range dd {
			m[d.Type] = d
		}
		str := ""
		deg := 0
		containsAny := func(str string, subStrings... string) bool {
			for _, s := range subStrings {
				if strings.Contains(str, s) {
					return true
				}
			}
			return false
		}
		if containsAny(m["ma"].Desp, "散在", "出现", "疑似") {
			if deg < 1 {
				deg = 1
			}
		}
		if containsAny(m["ex"].Desp, "散在", "出现", "疑似") {
			if deg < 3 {
				deg = 3
			}
		}
		if containsAny(m["ha"].Desp, "散在", "出现", "疑似") {
			if deg < 2 {
				deg = 2
			}
		}
		if deg == 0 {
			str = "未见DR"
		}
		if deg == 1 {
			str = "轻度NPDR"
		}
		if deg == 2 {
			str = "中度NPDR"
		}
		if deg == 3 {
			str = "重度NPDR"
		}
		return eye + str
	}
	levlog.Trace(tplcontent)
	tplcontent.Datatablel = genTale(ddl)
	tplcontent.Datatabler = genTale(ddr)
	tplcontent.Desp = GenDesp("左眼", ddl) + GenDesp("右眼", ddr)
	tplcontent.Diag = GenDegree("左眼", ddl) + "," + GenDegree("右眼", ddr)
	tplcontent.Sugg = "定期随访"

	// read tex template
	templateContent, err := ioutil.ReadFile("static/template.tex")
	levlog.E(err)
	t := template.Must(template.New("report").Parse(string(templateContent)))
	outFileName := fmt.Sprint("data/", pa.ID, "_report")
	file, err := os.Create(outFileName + ".tex")
	err = t.Execute(file, tplcontent)
	levlog.E(err)
	tplcontent.File = outFileName + ".pdf"

	latexCmd := exec.Command("xelatex", "-output-directory=data", outFileName + ".tex")
	err = latexCmd.Run()
	levlog.E(err)

	c.Data["json"] = tplcontent
	c.Redirect(fmt.Sprint("/api/image/", pa.ID, "_report.pdf"), 303)
	c.ServeJSON()
}
